package org.xobo.finance.helper.invoice.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xobo.finance.helper.invoice.domain.InvoiceMonthSummary;
import org.xobo.finance.helper.invoice.repository.InvoiceRepository;
import org.xobo.finance.helper.invoice.service.InvoiceCompanyCalcService;

@Service
public class InvoiceCompanyCalcServiceImpl implements InvoiceCompanyCalcService {

  @Override
  public Map<Long, BigDecimal> calcCompanyRecentSalesAmount(Collection<Long> companyIdList) {
    Collection<Map<String, Object>> amountList =
        invoiceRepository.loadCompanyAmount(getOneYearAgo(), companyIdList);

    return amountList.stream().collect(Collectors.toMap(x -> MapUtils.getLong(x, "companyId"),
        x -> new BigDecimal(Objects.toString(x.get("totalAmount"), "0"))));

  }

  private BigDecimal maxLimit = new BigDecimal(500_0000);

  @Override
  public Collection<InvoiceMonthSummary> loadCompanyYearMonthAmount(Long companyId) {
    LocalDate oneYearAgo = getOneYearAgo();
    List<String> pastYearMonthList = getNYearMonthListFrom(oneYearAgo, 12);
    List<String> futureYearMonthList = getNYearMonthListFrom(LocalDate.now(), 12);


    Map<String, Object> yearMonthMap = invoiceRepository
        .loadCompanyYearMonthAmount(getOneYearAgo(), companyId).stream().collect(Collectors
            .toMap(x -> Objects.toString(x.get("yearMonth"), ""), v -> v.get("totalAmount")));


    List<InvoiceMonthSummary> resultList = new ArrayList<>(pastYearMonthList.size());

    BigDecimal totalIssued = BigDecimal.ZERO;
    for (int i = 0; i < 12; i++) {
      String pastYearMonth = pastYearMonthList.get(i);
      String futureYearMonth = futureYearMonthList.get(i);

      BigDecimal amount =
          (BigDecimal) MapUtils.getObject(yearMonthMap, pastYearMonth, BigDecimal.ZERO);
      totalIssued = totalIssued.add(amount);

      InvoiceMonthSummary invoiceMonthSummary = new InvoiceMonthSummary();
      invoiceMonthSummary.setIssuedYearMonth(pastYearMonth);
      invoiceMonthSummary.setIssuedTotalAmount(amount);
      invoiceMonthSummary.setFutureYearMonth(futureYearMonth);
      resultList.add(invoiceMonthSummary);
    }

    for (int i = 0; i < 12; i++) {
      InvoiceMonthSummary invoiceMonthSummary = resultList.get(i);
      invoiceMonthSummary.setFutureTotalAmount(maxLimit.subtract(totalIssued));
      totalIssued = totalIssued.subtract(invoiceMonthSummary.getIssuedTotalAmount());
    }

    return resultList;
  }



  public static LocalDate getOneYearAgo() {
    return LocalDate.now().minusYears(1).plusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
  }

  public static List<String> getNYearMonthListFrom(LocalDate oneYearAgo, int n) {
    List<String> yearMonthList = new ArrayList<>(n);
    DateTimeFormatter ymFormatter = DateTimeFormatter.ofPattern("YYYY-MM");
    for (int i = 0; i < n; i++) {
      yearMonthList.add(ymFormatter.format(oneYearAgo));
      oneYearAgo = oneYearAgo.plusMonths(1);
    }
    return yearMonthList;
  }

  public static void main(String[] args) {
    System.out.println(getOneYearAgo());
    System.out.println(getNYearMonthListFrom(getOneYearAgo(), 12));
  }

  @Autowired
  private InvoiceRepository invoiceRepository;

}
